#include "MyString.h"
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>

#include <iostream>
#include <sstream>



//#define _CRT_SECURE_NO_WARNINGS


char MyString::PrintBuffer[MyString::PrintBufferLength]  ={0};

#define ARRAY_LENGTH(x)	(sizeof(x) / sizeof(x[0]))

	MyString::MyString()
	{
		Reset();
	}

	MyString::~MyString()
	{
		Release();
	}

	MyString::MyString(char *p)
	{
		Reset();
		Set(p);
	}

	MyString::MyString(int n)
	{
		Reset();
		Set(n);
	}

	void MyString::Set(int n)
	{
		Release();

		mSize = Digits(n) + 1; 

		mpBuffer = new char[mSize];

		/*std::stringstream ss;
		ss << n;
		ss.str();*/

		// convert int to string using stl function itoa
		itoa(n,mpBuffer,10);

		//Set(ss.str());


	}

	// get number of digits in an int
	int MyString::Digits(int n)
	{
		if(n==0)
			return 1;

		int i=0;
		if (n<0) 
		{
			i++;
			n= -n;
		}
		while (n)
		{
			n/=10;
			i++;
		}
		return i;
	}


	void MyString::Set(const char *pStr)
	{
		Release();

		mSize = strlen(pStr) + 1;

		mpBuffer = new char[mSize];

		memset(mpBuffer,0,mSize);

		strcpy(mpBuffer,pStr);
	}

	const char *MyString::Get() const
	{
		return mpBuffer;
	}

	void MyString::Concatenate(const MyString& rStr)
	{
		Concatenate(rStr.Get());
	}

	void MyString::Concatenate(const char *pStr)
	{
		mSize += strlen(pStr);

		char *p = new char[mSize];
		memset(p,0,mSize);

		strcpy(p,mpBuffer);
		strcat(p,pStr);

		delete[] mpBuffer;

		mpBuffer = p;
	}

	void MyString::ToUpper()
	{
		char *p = mpBuffer;

		while(*p != NULL)
		{
			*p = toupper(*p);
			p++;
		}
	}

	void MyString::ToLower()
	{
		char *p = mpBuffer;

		while(*p != NULL)
		{
			*p = tolower(*p);
			p++;
		}
	}

	void MyString::Release()
	{
		if(mpBuffer)
		{
			delete[] mpBuffer;
		}

		Reset();
	}

	void MyString::Print(char *format, ...)
	{
		char *pBuffer  = PrintBuffer;

		va_list ap;
		va_start(ap, format);
		unsigned int CharCount = vsprintf_s(pBuffer,ARRAY_LENGTH(PrintBuffer), format, ap);

		va_end(ap);

		Set(PrintBuffer);

	}

	void MyString::Reset()
	{
		mpBuffer = NULL;
		mSize = 0;
	}



	void MyString::operator= (const char *p)
	{
		Set(p);
	}

	void MyString::operator= (const MyString& rStr)
	{
		Set(rStr.Get());
	}

	void MyString::operator+= (const char *p)
	{
		Concatenate(p);
	}

	// convert int to string and concat
	void MyString::operator+= (int n)
	{
		Concatenate(MyString(n));
	}


	void MyString::operator+= (const MyString& rStr)
	{
		Concatenate(rStr);
	}

	bool MyString::operator== (const MyString& rStr) const
	{
		return strcmp(Get(),rStr.Get())==0?true:false;
	}

	MyString MyString::operator+ (const MyString& rStr)
	{
		/*MyString ret;

		ret = *this;
		ret += rStr;*/

		Concatenate(rStr);

		return *this;
	}

	MyString MyString::operator+ (const char *p)
	{
		/*MyString ret;

		ret = *this;
		ret += p;*/

		Concatenate(p);

		return *this;
	}

	// compare 2 strings - case insensitive! not very efficient..
	bool MyString::StringCompare(const char* string1, const char* string2 )
	{
		// if different lengths
		if(strlen(string1) != strlen(string2))
			return false;

		int comparison = strcmp(string1,string2);

		if(comparison == 0)
			return true;
		else
			return false;
	}
